package com;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

/**
 * Created by bruce on 2016/5/22.
 */
public class DateUtil {

    /**
     * DateFormat cache map
     */
    protected static Map<String, DateFormat> dateFormatMap = new HashMap<String, DateFormat>();

    /**
     * Date format pattern
     */
    public final static String FORMAT_DATE_DEFAULT = "yyyy-MM-dd";
    public final static String FORMAT_DATE_YYYY = "yyyy";
    public final static String FORMAT_DATE_YYYYMM = "yyyyMM";
    public final static String FORMAT_DATE_YYYYMMDD = "yyyyMMdd";
    public final static String FORMAT_DATE_YYYY_MM_DD = "yyyy-MM-dd";
    public final static String FORMAT_DATE_SLASH_YYYY_MM_DD = "yyyy/MM/dd";
    public final static String FORMAT_DATE_SLASH_YYYY_M_DD = "yyyy/M/dd";
    public final static String FORMAT_DATE_SLASH_YYYY_MM_D = "yyyy/MM/d";
    public final static String FORMAT_DATE_SLASH_YYYY_M_D = "yyyy/M/d";

    /**
     * DateTime format pattern
     */
    public final static String FORMAT_DATETIME_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public final static String FORMAT_DATETIME_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public final static String FORMAT_DATETIME_YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
    public final static String FORMAT_DATETIME_YYYY_MM_DD_HHMM = "yyyy-MM-dd HHmm";
    public final static String FORMAT_DATETIME_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public final static String FORMAT_DATETIME_YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HHmmss";
    public final static String FORMAT_DATETIME_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    /**
     * Time format pattern
     */
    public final static String FORMAT_TIME_DEFAULT = "HH:mm:ss";
    public final static String FORMAT_TIME_HH_MM = "HH:mm";
    public final static String FORMAT_TIME_HHMM = "HHmm";
    public final static String FORMAT_TIME_HH_MM_SS = "HH:mm:ss";
    public final static String FORMAT_TIME_HHMMSS = "HHmmss";

    public final static String KW_DATE_FORMAT = "yyyy-'KW'ww";

    public final static String IS_DATE_YYYY_MM_DD = "^(\\d{4})-(\\d{2})-(\\d{2})$";

    /**
     * Returns DateFormat according to given pattern which is cached.<br/>
     * This method is not public due to that the DateFormat instance may be
     * altered by outside.
     *
     * @param formatPattern date format pattern string
     * @return Cached DateFormat instance which should not be altered in any
     * way.
     */
    protected static DateFormat getCachedDateFormat(String formatPattern) {

        DateFormat dateFormat = dateFormatMap.get(formatPattern);

        if (dateFormat == null) {

            dateFormat = new SimpleDateFormat(formatPattern);
            dateFormatMap.put(formatPattern, dateFormat);

        }

        return dateFormat;

    }

    /**
     * Returns DateFormat according to given pattern.
     *
     * @param formatPattern date format pattern string
     * @return DateFormat instance.
     */
    public static DateFormat getDateFormat(String formatPattern) {

        return new SimpleDateFormat(formatPattern);

    }

    /**
     * Format the date according to the pattern.
     *
     * @param date          Date to format. If it's null, the result will be null.
     * @param formatPattern Date format pattern string. You can find common ones in
     *                      DateUtils class.
     * @return Formatted date in String
     * @see DateUtil
     */
    public static String formatDate(Date date, String formatPattern) {
        if (date == null) {
            return null;
        }
        return getCachedDateFormat(formatPattern).format(date);
    }

    /**
     * Format the date in default pattern: yyyy-MM-dd.
     *
     * @param date Date to format. If it's null, the result will be null.
     * @return Formatted date in String
     * @see DateUtil#FORMAT_DATE_DEFAULT
     * @see DateUtil#formatDate(Date, String)
     */
    public static String formatDate(Date date) {
        return formatDate(date, FORMAT_DATE_DEFAULT);
    }

    /**
     * Format the date in default date-time pattern: yyyy-MM-dd HH:mm:ss
     *
     * @param date Date to format. If it's null, the result will be null.
     * @return Formatted date-time in String
     * @see DateUtil#FORMAT_DATETIME_DEFAULT
     * @see DateUtil#formatDate(Date, String)
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, FORMAT_DATETIME_DEFAULT);
    }

    /**
     * Format the date in default time pattern: HH:mm:ss
     *
     * @param date Date to format. If it's null, the result will be null.
     * @return Formatted time in String
     * @see DateUtil#FORMAT_TIME_DEFAULT
     * @see DateUtil#formatDate(Date, String)
     */
    public static String formatTime(Date date) {
        return formatDate(date, FORMAT_TIME_DEFAULT);
    }

    /**
     * Returns current system date.
     *
     * @return current system date.
     * @see Date#Date()
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * Parse string value to Date by given format pattern. If parse failed, null
     * would be returned.
     *
     * @param stringValue   date value as string.
     * @param formatPattern format pattern.
     * @return Date represents stringValue, null while parse exception occurred.
     */
    public static Date parse(String stringValue, String formatPattern) {

        try {
            return getCachedDateFormat(formatPattern).parse(stringValue);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 功能：返回d1-d2的天数
     *
     * @param d1 Date
     * @param d2 Date
     * @return int
     */
    public static int diff(Date d1, Date d2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d1);
        int begind = cal.get(Calendar.DAY_OF_YEAR);
        cal.setTime(d2);
        int endd = cal.get(Calendar.DAY_OF_YEAR);
        return begind - endd;
    }

    /**
     * 比较返回日期大的日期对象，如果相等取d1对象,如果某个为空则取不为空的对象，如果都为空则返回null
     *
     * @param d1
     * @param d2
     * @return
     */
    public static Date getMaxDate(Date d1, Date d2) {
        if (d1 == null && d2 != null) {
            return d2;
        } else if (d1 != null && d2 == null) {
            return d1;
        } else if (d1 == null && d2 == null) {
            return null;
        } else if (d1.getTime() > d2.getTime()) {
            return d1;
        } else if (d1.getTime() < d2.getTime()) {
            return d2;
        } else {
            return d1;
        }
    }

    public static boolean isDate(String str) {
        if (StringUtils.isBlank(str))
            return false;
        Pattern pattern = Pattern.compile(IS_DATE_YYYY_MM_DD);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    public static Date getDate(String str) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(str);

        return date;
    }

    //时间戳转时间
    public static String unixTimeToTimestamp(Long unixTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (unixTime.longValue() == 0L)
            sdf = new SimpleDateFormat("0000-00-00 00:00:00");
        else {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        return sdf.format(new Date(unixTime.longValue() * 1000L));
    }

    //时间转时间戳
    public static Long timestampToUnixTime(String date) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date newdate = format.parse(date);
        return newdate.getTime() / 1000;
    }

    //格式化時间
    public static String formatDate(Object date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (date == null) {
            sdf = new SimpleDateFormat("0000-00-00 00:00:00");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
        return sdf.format(date);
    }

    //根据时间动态来生成订单号
    public static String getPayNum() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        return df.format(date);
    }

}